#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "./getch/getch.h"

#define MAXWORD 100

// Author Stat: founfed 2017 11 26
static int count_line = 1;

struct line
{
	int line;
	struct line *next;	
};

struct tnode 		// the tree node:
{
	char *word;	// points to the test
	struct line *start;
	struct tnode *next;
};

struct tnode *addltem(struct tnode *, char *);
struct line *addlines(struct line *);
void showltem(struct tnode *);
void showLine(struct line *);
struct tnode *lalloc(void);
struct line *Lalloc(void);
char *walloc(char *);
int getword(char *, int);
int Nonrealword(char *);


int main(void)
{
	struct tnode *head;
	char word[MAXWORD];
	
	head = NULL;	
	
	while(getword(word, MAXWORD) != EOF)
	{
		if(Nonrealword(word))
			if(isalpha(word[0]))
				head = addltem(head, word);
	}
	printf("%33s\n\n", "Words Line Number");
	showltem(head);
	return 0;
}

struct tnode *addltem(struct tnode *p, char *w)
{
	if(p == NULL)		
	{
		if((p = lalloc()) == NULL)
		{
			printf("Out of memory!\n");
			exit(EXIT_FAILURE);
		}
		if((p->word = walloc(w)) == NULL)
		{
			printf("Out of memory!\n");
			exit(EXIT_FAILURE);
		}
		if((p->start = Lalloc()) == NULL)
		{
			printf("Out of memory!\n");
			exit(EXIT_FAILURE);
		}
		p->start->line = count_line;
		p->start->next = NULL;
		p->next = NULL;
	}
	else if(strcmp(p->word, w) == 0)
		p->start = addlines(p->start);	
	else
		p->next = addltem(p->next, w);

	return p;
}

struct line *addlines(struct line *p)
{
	if(p == NULL)
	{
		if((p = Lalloc()) == NULL)
		{
			printf("Out of memory!\n");
			exit(EXIT_FAILURE);
		}
		p->line = count_line;
		p->next = NULL;
	}
	else if(p->line == count_line)
		;
	else
		p->next = addlines(p->next);
	return p;
}

void showltem(struct tnode *p)
{
	if(p != NULL)
	{
		printf("%20s ", p->word);
		showLine(p->start);
		printf("\n");
		showltem(p->next);
		free(p);
	}
}

void showLine(struct line *p)
{
	if(p != NULL)
	{
		printf("%d ", p->line);
		showLine(p->next);
		free(p);
	}
}

struct tnode *lalloc(void)
{
	return (struct tnode *)malloc(sizeof(struct tnode));
}

struct line *Lalloc(void)
{
	return (struct line *)malloc(sizeof(struct line));
}

char *walloc(char *w)
{
	char *p;

	if((p = (char *)malloc(strlen(w)+1)) != NULL)
		strcpy(p, w);
	return p;
}

int Nonrealword(char *s)
{
	int i;
	static char *list[] = {
		"a", "an", "and", "be", "but", "by", "he", "I", "is", "off", "on",
		"she", "so", "the", "they", "you", NULL
	};

	i = 0;
	while(list[i])
	{
		if(strcmp(list[i], s) == 0)
			return 0;
		i++;
	}
	return 1;
}
